{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "import random\n",
    "from tqdm import tqdm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [],
   "source": [
    "city = [[0.4, 0.2439], [0.1707, 0.2293], [0.5171, 0.4439], [0.1463, 0.2293], [0.761, 0.9414], [0.8732, 0.6878], [0.8488, 0.6683], [0.6195, 0.6536], [0.5219, 0.3609], [0.2536, 0.2634]]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [],
   "source": [
    "def visualizer(path):\n",
    "    x = [p[0] for p in city]\n",
    "    y = [p[1] for p in city]\n",
    "    plt.plot(x, y, 'o')\n",
    "    city_reorder = [city[i] for i in path]\n",
    "    x_re = [p[0] for p in city_reorder]\n",
    "    y_re = [p[1] for p in city_reorder]\n",
    "    x_re.append(x_re[0])\n",
    "    y_re.append(y_re[0])\n",
    "    plt.plot(x_re, y_re, linewidth=1, color='red')\n",
    "    plt.savefig(\"path.png\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "distances = [[-1 for j in range(10)] for i in range(10)]\n",
    "\n",
    "def computePointDistance(x, y):\n",
    "    if distances[x][y] >= 0:\n",
    "        return distances[x][y]\n",
    "    else:\n",
    "        distances[x][y] = math.sqrt((city[x][0] - city[y][0]) ** 2 + (city[x][1] - city[y][1]) ** 2)\n",
    "    return distances[x][y]\n",
    "\n",
    "def computePathDistance(path):\n",
    "    totalDistance = 0.0\n",
    "    for i in range(10):\n",
    "        if i == 9:\n",
    "            distance = computePointDistance(path[9], path[0])\n",
    "        else:\n",
    "            distance = computePointDistance(path[i], path[i+1])\n",
    "        totalDistance += distance\n",
    "    return totalDistance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ACO(n_epochs = 2000, c = 2., m = 50, alpha = 1, beta = 3, sigma = 0.1, Q = 100):\n",
    "    tao = np.zeros(shape = (10, 10))\n",
    "    tao.fill(c)\n",
    "    all_best_distance = 1000.0\n",
    "    all_best_path = None\n",
    "    best_distances = []\n",
    "    avg_distances = []\n",
    "    for i in tqdm(range(n_epochs)):\n",
    "        _tao = np.zeros(shape = (10, 10))\n",
    "        best_distance = 1000.0\n",
    "        avg_distance = 0.0\n",
    "        for k in range(m):\n",
    "            visited = []\n",
    "            state = np.random.randint(0, 10)\n",
    "            visited.append(state)\n",
    "            while len(visited) != 10:\n",
    "                # print(visited)\n",
    "                total = 0.0\n",
    "                p = np.array([0. for _ in range(10)])\n",
    "                for num in range(10):\n",
    "                    if num != state:\n",
    "                        if num not in visited:\n",
    "                            distance = 1.0 / computePointDistance(state, num)\n",
    "                            info = tao[state][num]\n",
    "                            total += distance ** beta * info ** alpha\n",
    "                    p[num] = total\n",
    "                p = p / total\n",
    "                rd = np.random.uniform(0, 1)\n",
    "                for num in range(10):\n",
    "                    if rd < p[num]:\n",
    "                        state = num\n",
    "                        visited.append(num)\n",
    "                        break\n",
    "\n",
    "            total_distance = computePathDistance(visited)\n",
    "            avg_distance += total_distance\n",
    "            if total_distance < best_distance:\n",
    "                best_distance = total_distance\n",
    "                best_path = visited\n",
    "\n",
    "            for t in range(10):\n",
    "                if t == 9:\n",
    "                    _tao[visited[9]][visited[0]] += Q / total_distance\n",
    "                    _tao[visited[0]][visited[9]] += Q / total_distance\n",
    "                else:\n",
    "                    _tao[visited[t]][visited[t+1]] += Q / total_distance\n",
    "                    _tao[visited[t+1]][visited[t]] += Q / total_distance\n",
    "\n",
    "        avg_distance /= m\n",
    "        tao = (1 - sigma) * tao + _tao\n",
    "        best_distances.append(best_distance)\n",
    "        if best_distance < all_best_distance:\n",
    "            all_best_distance = best_distance\n",
    "            all_best_path = best_path\n",
    "        avg_distances.append(avg_distance)\n",
    "\n",
    "    return all_best_distance, all_best_path, best_distances, avg_distances\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 2000/2000 [00:14<00:00, 136.29it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.1678630605599585\n",
      "[9, 1, 3, 0, 8, 6, 5, 4, 7, 2]\n",
      "2.1678630605599585\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEGCAYAAAB/+QKOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABJvUlEQVR4nO2dd5wURfbAv49lYQlLBkXSgoIIyhIWBAExAipmvcNTzOLpoXKGn4KeeqdnPMN5BkThDMchd2ZFPcCEigkQAQFFTCQVQcKSd3m/P7p7t2emZ3Zmdnp3Wd7385nP9FRXV73prq5X9arqlagqhmEYhhFNjcoWwDAMw6iamIIwDMMwAjEFYRiGYQRiCsIwDMMIxBSEYRiGEUjNyhYgkzRr1kzz8vIqWwzDMIzdhjlz5vyiqs2DzlUrBZGXl8fs2bMrWwzDMIzdBhH5Pt45MzEZhmEYgZiCMAzDMAIxBWEYhmEEUq3GIAzDqDx27tzJihUr2LZtW2WLYgSQk5ND69atyc7OTvoaUxCGYWSEFStWkJubS15eHiJS2eIYPlSVtWvXsmLFCtq3b5/0dWZiMgwjI2zbto2mTZuacqiCiAhNmzZNuXcXmoIQkTYi8raILBKRL0TkioA4h4nIBhGZ535u9J37TkQWuOE2d9UwdgNMOVRd0nk2YZqYioCrVHWuiOQCc0Rkuqouior3nqoOi5PG4ar6S4gyOtx6K/TuDUOGhJ6VYRjG7kJoPQhVXa2qc93jTcBioFVY+ZWL22+HGTMqWwrDMMpJVlYW3bt3Jz8/n549ezJr1qy00rn//vvZsmVL4LnDDjuM/fffn27dutG5c2dGjRrF+vXrS84fcsghCdO+7bbb0pKpMqiQMQgRyQN6AB8HnO4nIp+LyOsi0tUXrsA0EZkjIiMTpD1SRGaLyOw1a9ZkVnDDMHYr6tSpw7x58/j888+5/fbbGTNmTFrpJFIQAJMmTWL+/PnMnz+f2rVrc+KJJ5acK0spmYLwISL1geeA0aq6Mer0XKCdquYD/wBe9J0boKo9gWOAP4jIoUHpq+p4VS1Q1YLmzQPdiSSH7axnGNWKjRs30rhx45Lfd999N71796Zbt27cdNNNAGzevJnjjjuO/Px8DjzwQKZMmcIDDzzAqlWrOPzwwzn88MMT5lGrVi3uuusufvjhBz7//HMA6tevD8Dq1as59NBD6d69OwceeCDvvfce1113HVu3bqV79+6ceeaZAJx00kn06tWLrl27Mn78+JK069evz/XXX09+fj59+/blp59+AuCnn37i5JNPJj8/n/z8/BKF9K9//Ys+ffrQvXt3Lr74YoqLi8t9D0Od5ioi2TjKYZKqPh993q8wVPU1EXlYRJqp6i+qutIN/1lEXgD6ADNDEjSUZA1jT+XPr3zBolXR7cHy0WWfBtx0fNeEcbzKd9u2baxevZq33noLgGnTprF06VI++eQTVJUTTjiBmTNnsmbNGvbZZx+mTp0KwIYNG2jYsCH33nsvb7/9Ns2aNStTrqysLPLz81myZAn5+fkl4f/+978ZMmQI119/PcXFxWzZsoWBAwfy4IMPMm/evJJ4EydOpEmTJmzdupXevXtz6qmn0rRpUzZv3kzfvn3561//yv/93//x2GOPccMNN3D55ZczaNAgXnjhBYqLiyksLGTx4sVMmTKFDz74gOzsbC699FImTZrE2WefncadLiU0BSHOkPkEYLGq3hsnzt7AT6qqItIHp0ezVkTqATVUdZN7PBj4S1iyGoZRPfBMTAAffvghZ599NgsXLmTatGlMmzaNHj16AFBYWMjSpUsZOHAgV111Fddeey3Dhg1j4MCBaeWrARaI3r17c/7557Nz505OOukkunfvHnjtAw88wAsvvADA8uXLWbp0KU2bNqVWrVoMG+bM3+nVqxfTp08H4K233uKpp54CHOXUsGFDnn76aebMmUPv3r0BR1G2aNEirf/iJ8weRH9gBLBAROa5YWOBtgCqOg44DbhERIqArcBwV1nsBbzgTsuqCfxbVd8IUVYzMRlGBimrpV8R9OvXj19++YU1a9agqowZM4aLL744Jt7cuXN57bXXuOGGGzjyyCO58cYbA1KLT3FxMQsWLOCAAw6ICD/00EOZOXMmU6dO5dxzz+XKK6+MadG/8847zJgxgw8//JC6dety2GGHlaxVyM7OLpmampWVRVFRUVwZVJVzzjmH22+/PSXZyyLMWUzvq6qoajdV7e5+XlPVca5yQFUfVNWuqpqvqn1VdZYb/o0blu+e/2tYcgJmYjKMasiSJUsoLi6madOmDBkyhIkTJ1JYWAjAypUr+fnnn1m1ahV169blrLPO4pprrmHu3LkA5ObmsmnTpjLz2LlzJ2PGjKFNmzZ069Yt4tz333/PXnvtxUUXXcSFF15YknZ2djY7d+4EHJNW48aNqVu3LkuWLOGjjz4qM88jjzySRx55BHCU04YNGzjyyCN59tln+fnnnwFYt24d338f14t30pirDcMwqg3eGAQ4reonn3ySrKwsBg8ezOLFi+nXrx/gDAD/61//4uuvv+aaa66hRo0aZGdnl1S8I0eOZOjQoeyzzz68/fbbMfmceeaZ1K5dm+3bt3PUUUfx0ksvxcR55513uPvuu8nOzqZ+/folZqGRI0fSrVs3evbsycSJExk3bhwHHHAA+++/P3379i3zP/79739n5MiRTJgwgaysLB555BH69evHrbfeyuDBg9m1axfZ2dk89NBDtGvXLt1bCYAE2c52VwoKCjStDYNyc+Gii+DewKESwzCSYPHixTFmFqNqEfSMRGSOqhYExTdfTGAmJsMwjABMQRiGYRiBmILwqEamNsMwjExgCgLMxGQYhhGAKQgP60EYhmFEYAoCrAdhGIYRgCkIwzCqFS+++CIiwpIlSzKS3hNPPEHz5s3p0aMHHTt2ZMiQIREeW2+88UZmJNgu4MUXX2TRouhtcHYPTEF4mInJMKoFkydPZsCAAUyePDljaf72t7/ls88+Y+nSpVx33XWccsopLF68GIC//OUvHHXUUXGvNQWxu2MmJsOoFhQWFvL+++8zYcIEnnnmGQDeeOMNTj/99JI477zzTokTvAkTJtCpUyf69OnDRRddxKhRo8rM4/DDD2fkyJElrrnPPfdcnn32WQCuu+46unTpQrdu3bj66quZNWsWL7/8Mtdccw3du3dn2bJlPPbYY/Tu3Zv8/HxOPfXUkn0nzj33XC6//HIOOeQQOnToUJImwJ133slBBx1Efn4+1113HQDLli1j6NCh9OrVi4EDB2asx+THXG0YhpF5Ro8Gn0vrjNC9O9x/f8IoL730EkOHDqVTp040bdqUOXPmcNRRRzFy5Eg2b95MvXr1mDJlCsOHD2fVqlXccsstzJ07l9zcXI444ogId92J6NmzJ48++mhE2Nq1a3nhhRdYsmQJIsL69etp1KgRJ5xwAsOGDeO0004DoFGjRlx00UUA3HDDDUyYMIHLLrsMcPaQeP/991myZAknnHACp512Gq+//jovvfQSH3/8MXXr1mXdunWA47Jj3LhxdOzYkY8//phLL720xL15prAehIeZmAxjt2fy5MkMHz4cgOHDhzN58mRq1qzJ0KFDeeWVVygqKmLq1KmceOKJfPLJJwwaNIgmTZqQnZ0d0csoiyAXRQ0bNiQnJ4cLLriA559/nrp16wZeu3DhQgYOHMhBBx3EpEmT+OKLL0rOnXTSSdSoUYMuXbqUbBA0Y8YMzjvvvJL0mjRpQmFhIbNmzeL0008v2SBo9erVScufLNaDADMxGUamKaOlHwbr1q3jrbfeYsGCBYgIxcXFiAh33303w4cP58EHH6RJkyYUFBSQm5tbrrw+++yzGJ9GNWvW5JNPPuHNN9/k2Wef5cEHHwxs0Z977rm8+OKL5Ofn88QTT/DOO++UnKtdu3bJcSI/ebt27aJRo0YRGw+FgfUgDMOoFjz77LOMGDGC77//nu+++47ly5fTvn173nvvPQYNGsTcuXN57LHHSnoYvXv35t133+XXX3+lqKiI5557Lql83n33XcaPH19iJvIoLCxkw4YNHHvssdx3330lW5BGuw7ftGkTLVu2ZOfOnUyaNKnM/I4++mj++c9/loxVrFu3jgYNGtC+fXv++9//Ao4y8fLLJKYgPMzEZBi7NZMnT+bkk0+OCDv11FOZPHkyWVlZDBs2jNdff71kgLpVq1aMHTuWPn360L9/f/Ly8mjYsGFg2lOmTKF79+506tSJ2267jeeeey6mB7Fp0yaGDRtGt27dGDBgAPe63qGHDx/O3XffTY8ePVi2bBm33HILBx98MP3796dz585l/q+hQ4dywgknUFBQQPfu3fnb3/4GwKRJk5gwYQL5+fl07do10OV4eTF33wBNm8Lvfgf/+EfmhTKMPYTd0d13YWEh9evXp6ioiJNPPpnzzz8/RslUJ6qMu28RaSMib4vIIhH5QkSuCIhzmIhsEJF57udG37mhIvKliHwtIteFJadhGHsuN998M927d+fAAw+kffv2nHTSSZUtUpUizEHqIuAqVZ0rIrnAHBGZrqrRK0beU9Vh/gARyQIeAo4GVgCfisjLAddmjmrUkzIMIzk8c40RTJh7Uq9W1bnu8SZgMdAqycv7AF+7e1PvAJ4BTgxHUmwWk2FkiOpksq5upPNsKmSQWkTygB7AxwGn+4nI5yLyuoh0dcNaAct9cVYQR7mIyEgRmS0is9esWZNJsQ3DSIGcnBzWrl1rSqIKoqqsXbuWnJyclK4LfR2EiNQHngNGq+rGqNNzgXaqWigixwIvAh1TSV9VxwPjwRmkTltQK9SGUS5at27NihUrsIZa1SQnJ4fWrVundE2oCkJEsnGUwyRVfT76vF9hqOprIvKwiDQDVgJtfFFbu2FhCRpa0oaxp5CdnU379u0rWwwjg4Q5i0mACcBiVb03Tpy93XiISB9XnrXAp0BHEWkvIrWA4cDLYclqGIZhxBJmD6I/MAJYICLz3LCxQFsAVR0HnAZcIiJFwFZguDoGzCIRGQX8D8gCJqrqF4SJmZgMwzAiCE1BqOr7QELbjao+CDwY59xrwGshiBaLmZgMwzBiMFcbhmEYRiCmIDzMxGQYhhGBKQgwE5NhGEYApiA8rAdhGIYRgSkIsB6EYRhGAKYgDMMwjEBMQXiYickwDCMCUxBgJibDMIwATEEYhmEYgZiC8DATk2EYRgSmIMBMTIZhGAGYgjAMwzACMQXhYSYmwzCMCExBgJmYDMMwAjAFYRiGYQRiCsLDTEyGYRgRhLnlaBsReVtEFonIFyJyRYK4vUWkSERO84UVi8g89xPudqNmYjIMw4ghzC1Hi4CrVHWuiOQCc0Rkuqou8kcSkSzgTmBa1PVbVbV7iPIZhmEYCQitB6Gqq1V1rnu8CVgMtAqIehnwHPBzWLIkhZmYDMMwIqiQMQgRyQN6AB9HhbcCTgYeCbgsR0Rmi8hHInJSgrRHuvFmr1mzJl0B07vOMAyjGhO6ghCR+jg9hNGqujHq9P3Ataq6K+DSdqpaAPwOuF9E9g1KX1XHq2qBqhY0b948k6IbhmHs0YQ5BoGIZOMoh0mq+nxAlALgGXFa8M2AY0WkSFVfVNWVAKr6jYi8g9MDWRaasGZiMgzDiCDMWUwCTAAWq+q9QXFUtb2q5qlqHvAscKmqvigijUWktptOM6A/sCgojQwJG1rShmEYuyth9iD6AyOABSIyzw0bC7QFUNVxCa49AHhURHbhKLE7omc/GYZhGOESmoJQ1feBpJvmqnqu73gWcFAIYiUSoEKzMwzDqOrYSmowE5NhGEYApiA8rAdhGIYRgSkIsB6EYRhGAKYgDMMwjEBMQXiYickwDCMCUxBgJibDMIwATEEYhmEYgZiC8DATk2EYRgRJKQgRaSciR7nHddz9HaoPZmIyDMOIoUwFISIX4fhJetQNag28GKJMhmEYRhUgmR7EH3D8Km0EUNWlQIswhaoUzMRkGIYRQTIKYruq7vB+iEhNoHrVpmZiMgzDiCEZBfGuiIwF6ojI0cB/gVfCFcswDMOobJJRENcBa4AFwMXAa8ANYQpVKZiJyTAMI4Jk3H3XASaq6mMAIpLlhm0JU7AKxUxMhmEYMSTTg3gTRyF41AFmhCOOYRiGUVVIRkHkqGqh98M9rhueSJWEmZgMwzAiSEZBbBaRnt4PEekFbC3rIhFpIyJvi8giEflCRK5IELe3iBSJyGm+sHNEZKn7OScJOdPHTEyGYRgxJDMGMRr4r4iswtlCdG/gt0lcVwRcpapz3ZXXc0RkevTe0u6Yxp3ANF9YE+AmoABnSu0cEXlZVX9NIl/DMAwjA5SpIFT1UxHpDOzvBn2pqjuTuG41sNo93iQii4FWwKKoqJcBzwG9fWFDgOmqug5ARKYDQ4HJZeWbNmZiMgzDiCCZHgQ4lXeeG7+niKCqTyWbiYjkAT2Aj6PCWwEnA4cTqSBaAct9v1e4YUFpjwRGArRt2zZZkaITSe86wzCMakyZCkJEngb2BeYBxW6wAkkpCBGpj9NDGK2qG6NO3w9cq6q7JM1KWlXHA+MBCgoKrBtgGIaRIZLpQRQAXVRTt8GISDaOcpikqs/HSfsZVzk0A44VkSJgJXCYL15r4J1U808JMzEZhmFEkIyCWIgzML06lYTFqfUnAItV9d6gOKra3hf/CeBVVX3RHaS+TUQau6cHA2NSyT8lzMRkGIYRQzIKohmwSEQ+AbZ7gap6QhnX9QdGAAtEZJ4bNhZo614/Lt6FqrpORG4BPnWD/uINWIeG9SAMwzAiSEZB3JxOwqr6Ps602GTjnxv1eyIwMZ28U8Z6EIZhGDEkM8313YoQxDAMw6haJLOjXF8R+VRECkVkh4gUi0j0bKTdHzMxGYZhRJCMq40HgTOApTiO+i4EHgpTqArHTEyGYRgxJKMgUNWvgSxVLVbVf+KsajYMwzCqMckMUm8RkVrAPBG5C2e6a1KKZbfCTEyGYRgRJFPRj3DjjQI2A22AU8IUqsIxE5NhGEYMySiIk1R1m6puVNU/q+qVwLCwBTMMwzAql2QURNBeDOdmWI7Kx0xMhmEYEcQdgxCRM4DfAe1F5GXfqQZAuKuaKxozMRmGYcSQaJB6Fs6AdDPgHl/4JmB+mEIZhmEYlU9cBaGq3wPfi8hRwFbXJXcnoDOwoKIErDDMxGQYhhFBMmMQM4Ecd3OfaTizmp4IU6gKx0xMhmEYMSSjIERVt+BMbX1YVU8HuoYrlmEYhlHZJKUgRKQfcCYw1Q3LCk+kSsJMTIZhGBEkoyBG42zW84KqfiEiHYC3Q5WqojETk2EYRgzJuvt+1/f7G+DyMIUyDMMwKp9E6yDuV9XRIvIKEGN/SWJHud0LMzEZhmFEkKgH8bT7/bd0EhaRNsBTwF44Cma8qv49Ks6JwC3ALqAIGO3uRIeIFFM6nfaHUBWSmZgMwzBiSLQOYo77/a6INHeP16SQdhFwlarOFZFcYI6ITFfVRb44bwIvq6qKSDfgPzjrLMBZe9E9hfwMwzCMDJJwkFpEbhaRX4Avga9EZI2I3JhMwqq6WlXnusebgMVAq6g4haoltp16BJiyKgwzMRmGYUQQV0GIyJVAf6C3qjZR1cbAwUB/EfljKpmISB7QA/g44NzJIrIEZwrt+b5TOSIyW0Q+EpGTEqQ90o03e82aVDo4EYmkd51hGEY1JlEPYgRwhqp+6wW4M5jOAs5ONgMRqQ88hzO+ELOXtaq+oKqdgZNwxiM82qlqAY7DwPtFZN+g9FV1vKoWqGpB8+bNkxUrKKH0rzUMw6iGJFIQ2ar6S3SgOw6RnUziIpKNoxwmqerzieKq6kygg4g0c3+vdL+/Ad7B6YGEg/UgDMMwYkikIHakeQ5wll8DE4DFqnpvnDj7ufEQkZ5AbWCtiDQWkdpueDMcU9eioDQMwzCMcEg0zTVfRGJMQoAAOUmk3R/HTLVAROa5YWOBtgCqOg44FThbRHYCW4HfujOaDgAeFZFdOErsjqjZT5nHTEyGYRgRJJrmWi5/S+56hoS2G1W9E7gzIHwWcFB58k8JMzEZhmHEkIwvJsMwDGMPxBSEh5mYDMMwIjAFAVCjhikIwzCMKExBgKMgdu2qbCkMwzCqFGUqCBE5RUSWisgGEdkoIpvizG7afTEFYRiGEUOZ+0EAdwHHq+risIWpNExBGIZhxJCMiemnaq0cwFEQb70Fy5ZVtiSGYRhVhkQbBp3iHs4WkSnAi8B273xZrjN2K2rUgKIi2G8/G6w2DMNwSWRiOt53vAUY7PutQPVSEIZhGEYEiVZSnwcgIv1V9QP/ORHpH7ZgFUpWuRaNG4ZhVEuSaTr/I8mw3RfrQRiGYcSQaAyiH3AI0NzdPMijAVC9mtymIAzDMGJINAZRC6jvxsn1hW8ETgtTqArHFIRhGEYMicYg3gXeFZEnVPX7CpSp4vnf/ypbAsMwjCpHMgvltojI3UBXfPtAqOoRoUm1OzN9OvTtC7m5Zcc1DMOowiRjW5kELAHaA38GvgM+DVGm3ZcffoDBg+GccypbEsMwjHKTjIJoqqoTgJ2q+q6qng9Y7yGIwkLne8mSypXDMAwjAySjIHa636tF5DgR6QE0KesiEWkjIm+LyCIR+UJErgiIc6KIzBeReSIyW0QG+M6d4zoJXCoiFdckv/TS9K+tiFXYs2fD+++Hn8/uwPbtzgp4w6hKFBfD2LHwyy+VLUm5SUZB3CoiDYGrgKuBx4E/JnFdEXCVqnYB+gJ/EJEuUXHeBPJVtTtwvps2ItIEuAk4GOgD3CQijZPIs/w88kjk75NOgnr1UksjzC1Me/eGgQPDS393IicHBg2qbCkMI5I33oDbby9fY7OKkGgdRA7we2A/oBUwQVUPTzZhVV0NrHaPN4nIYjedRb44hb5L6uG48AAYAkxX1XWuLNOBocDkZPPPCMuWwUsvJR/f/DhVPLNmVbYEhgHr1zsNyezs0l7t9u0JL8kIs2Y5E2IOOiiU5BP1IJ4ECoAFwDHAPelmIiJ5QA/g44BzJ4vIEmAqTi8CHEWy3BdthRsWlPZI1zw1e82aNemKGEynTqnF9xREmD2IZFi6FLZtq1wZDGNPonFjOPXUcNJ+7TV47LHgc/37Q7du4eRLYgXRRVXPUtVHcRbGpWXXEJH6wHPAaFWN2WhIVV9Q1c7AScAtqaavquNVtUBVC5o3b56OiPGnpKa6R0RVUBCbNzuKzWZSGUY4/PADbN0aG/7KK+Hkd9xxMHJkOGmXQSIF4Q1Oo6ppjQSKSDaOcphUlntwVZ0JdBCRZsBKoI3vdGs3LBzatYsN27kz8ncy5qPKUBDffguHHAK//ur83rLF+X7rrYqTwTD2JNq1g5NPjn++GpmaEymIfHeL0Y0isgnolsqWoyIiwARgsareGyfOfm48RKQnUBtYC/wPGCwijd3B6cFuWDhEu9p4/HH4858jw4qLy07nwQed7zAUxKJF8GnA8pPbboMPP4Rnn3V+V4VejFH12LULFlfvfb8qlD3E+0JcBaGqWarawP3kqmpN33GDJNLuD4wAjnCnsc4TkWNF5Pci8ns3zqnAQhGZBzwE/FYd1uGYmz51P3/xBqxDIVpBXHSRY8f3k8x0yscfT3z+7rudinvHjtTkA+jaFfr0iX/eUwymIDLD1q2O8o3uSQbxzTfO/f7vf8OXK13++lfo0gUWLKhsSVJj2TL48cfKlmKPJTQvdar6vqqKqnZT1e7u5zVVHaeq49w4d6pqV/dcP1V933f9RFXdz/38Myw5geDKNLqb+MEHybfA4lXOt93mfG/enPj6DRvgggtKF96lkpc3bmIKonzccQdcf33s4OCSJbFKY9485/vf/64Q0VLmgw+caZcAy5cnjlvV2G8/aNmysqVIjfK+e6+8AqecUiXeYXNjGo/o1uBRRzktsPJMXUvWNnnnnTBxIvwjjW03PAURpofaoiJHxrBmSqlCfj785z+R4bt2Ob27hQvDydfPpk3Ot38w8ocf4IAD4JprIuN6L3JZz3fLFujc2amwK5IBA0r/RzWyjyfFv/4F992XufTCvH+TJjkNkxNOgBdeCC+fFDAFAalp6ptugltuia0cv/oqvfSCSKcQRpuYVq8ubdlmmgkT4LrrSntEmWDrVmdh0a+/Oia4+fNhxIjIOMuWOWa8RAOEmcb/LL1p1DNnRsbxlHFZz+3zz+HLL+GqqzInX6oUFsLFF5dOaqjujBgBV15ZdrxkCZrZGP3c01UiZ50FY8akd21ImIKA1Frbd94JN94Id90VGT50aOlxRXYNo1uv/sLZo0f50583L/al8FrXZZnKUuHxx51V7LfcEvkftmwpzT+TrbfFi+G99zKTlvcMypoWnWxPI0wmT4bx4x1XEGGi6rwn1W1gPOjZRYd5lXwVMBGVF1MQkN6DjB4fSMX0JOLYscuaGZVMRRJvDMJjxw6ntf/aa8nL5zF7tqNkonsKYZixvOm5NWuW/u8dO5zVqWG0uLt0gUMPjX8+6N7HKyeZrPhnz4Z/hjjk1qiR8x008FtUlDnl9euvjrI/PGnnC+kxa1bZk0Myif/+FBfD+ec7Mwz9VCNnnaYg0uXuu52Kcvt2eOCByMq+LIWjCrVqwZFHZl6uaKVz1VVOr+e445K7vrDQGZhVLR3QnD07Mo6nILIyuPOsZ7LLyYlVcuPHlz/9deuSm6ocTbwJDKqxijLVhZVB9O7tVDrJsmVLarPivGf24oux57Kz4ZJLkk/Ljyrcc4/jcsL7DenN2EuF/v2dcalkGTMG9t47/fz8CmLhQkeZ/+Y3ZcfdTTEFAVC3bnrXrVwJf/sbXHEF/PRTaXgyCgLg3XcTx0ulZ+OluTJqPeHcubFx77sv/oybSy5xVm1+8EH8/P0VY3Gxc//K24pLpCCSqWR27Ijvl2n9emja1OlJpSsXRN6Pyy93KtuHHiodf6oME1O9enDwwZlL79FHHflmzEhNzjffhKuvhj/8wfld3v+6Y0fwauXycscdzrt6772OjKnksXp1aQ/Mj/8/hqkUKsFzsSkIgAbJLOsI4MorS1tMfuJVrF5lk2whKiteUVHsOEC02cQvy2efOd9XXglnnhmc5vfu7rLFxfHz9yrCHTuc8YitWx0lmS4zZ5ZWsllZsS39sl6Mzz6D2rWd1uQXX8SeX+cuoXnuudhzZVXqQbZ61dJFkaNGlQ6ClvW8wrJJpzsZId406kmT4OijnZl00bz5ZvBaCq+i3bAhMjxds1XPnuk33JLhHte13Pz5znNJZuHb9OnBCsVfhjKtIPzpZWdnNu0kMAVRHp591ulBRBNUEcycWTpOccMNidO9447k8j/nHGcaXyL8c/Z79nRccyTCewHq1IkM/89/HIWwaFHpFLx77oGCAue4rMrvmWfgvPOCzw0aBM8/X5pOWZX2119H/p7sc/KbaHbOt99Cv36RvYLLLkveNJRszzAeXu8umUrkk0+SkylV/Hn7x3b84W+/7Xx7jQU/Rx0V7BzOu37ePPj559LfhYVw4YWpyxmk6DOJ9yw//ND5jjZjduwIw4c79+Cjj5xeR8OGwWn5ZzD676OIMw5TnjG06LJy222lz6cCTFimIMLkyy+dlwWcRVce48aVP+1VqyLNRPEKS3RFM2pU4nS9yrNWrdKw11+H3/7WmZXStWuk2WrZssT5e5xxBjzxRGTY1q3BlXMyFfa0aaXH/h7ge+/FrpPwy/bRR850U4+HH3ZeYj8ffeS0LOMR779On+6sOQg6v3ats/gp0fX+Fn1Ybsz9efs3tPGHez2HmslsWU+kOWjlSqfR4H+GEyc6invYsNL3IVWWL8/supvoCRbe/3/wQefZf/01TJkCeXlOo+Kgg5xeatA1fqLL7o03OuasRLz7rtMzCyK693z99XDEEbF5TZ+eOI80MQURBl7rpHNnOPBApxWfjrb3Vr8G0SrK+3m8AhZN9GymDRsiV9d6cvoLnzcGcOedyeWRDN7YxejRkeGqsf8tCL/M/g2dxo4t2zd+dE/gnXcif/frF+zsMBkT0QcfBFdkzZqVHq9cGbsae8eOSK/C6bYOv/wyskWbCH8l6c0i85PsJIQuXZzWtsfy5bEV5aOPwtSpZVeW8WjbFn73u/SuhdhZW9HP0rvfl13mLNKMZs2a2P8UPdUdym7cdOoEf/qTY/YcO9ZpOBx2mNMzC+Lmm4PDO3eONOcNHpw43zQxBQHhdNW8NNescVrj8VbP9u8fP43CwuTNH56JJlW6dnVePg/vxSkuTs1m7sWdPTtyUHnKlMh07r/f+fbiBK0WT2ZQ2t+ySral65Foem6inoNHMmNDfqLNej/+6MxU8j/bskx/4JjpZs92KvN4e5907gz77192WhD5XG69NfZ8Mu/FtGmlvUg/r74a+dt7puWxoyezedfGjaVjbX5atozs+frLOTjPoix33dFK3W/a9Cjrni1d6tzryy5zGoBB4zx+4sn05ZfOxIuQMQURBqtWJedHCco2JWR65oK/Mn3vvdhZT9EvTipMn+5M0/T7L/K3LAH++Ed4+un46SfrU9//spalIKJf2o0JnBFnwuGeJ9v27XDttdChQ2ycf/0rckwmGaV4xhnO/R0wAFq0cAaSU8V/L/yKcu3a2Lh//WvZ6b3+enB49LiDd09SVeZ+RJzpuUEz8zyOO84Zawta9+NftOf9dy+ssLDs6dTJPKNkG3SeedhbdBqPSl5sZwoCMv8QVqxIfcPyBQuCK8eiovA8cCZaKJaqghApbbl5reEVK4Ljnn12fC+p8cwj0YrSm0UEwZXO1q3OwKI3g8lP9PoTv/khqCykqqS9iuTxx4PNEB5PPVV6HD0bLVqp+XsY3n2eMSN+2osXw5NPJpZzypTS46DKL5M2f+95+8e20uHkk6FXr/jn33f9fR53XOlxtAxQ+pwnTHC+33orttcTTTKmu1TXwkSPf1UxTEGExerVqcXv1s1x0hX9on7+efJbCsZrzfmJV4C9WSPl6UF4rVCv69umTfy4zzyTWtpjx0ZWml9+WXoc7dQPnNlWe++dXDfcP3UxSEEce2zk77IUtlcRJaNYfvjB+Y4eA4h+Tn/8Y+J0omdvdekC554b2zOIVjzff++Y1fzKKprPPiu/Gda7J9EmpmRMa+kyMGoTTH+P7ZtvUk+vrNmHENkL8T//O+4IbqxUcUxBRNOxY2bSOfHE5OP6X+7oefeHHJJ8OtEVWRDxFITXbU93DAJKW8vxpgP6ufTS1NKeODGykhowoPQ4qCXtbz2W5ZjOG4y99FL4y19iz3szRKKn18Zj2zY47bTYFehBtGvnmGOGDIkMT1VBN2kSHB5dqUVX9Hl5MGdO/HTffdcx2Tz8cPD5ZMtIkIJYuNAxv3lrEqoD/imtU6eWHo8ZE+mvbTehHAbBaoT/pUl30Vw0qZiY/C93mC2qREQP3D7xROJWZTT+MZcwXI2vXRtp1442H0Tjnx2VaKMlcBTEqlWOs8B4PPFE/HUc0SxdGrwoLx6emcPP/fc74xc//+zIl0xF7J++6xE9pTpI8SRyVeENQI8aFamUvfySHWvzVtp7CqK42HFXA84K7DZtnFX0W7fGjlvFwz8YrZq8Aq8sgnaErOqoaigfnD2l3wYWAV8AVwTEOROYDywAZgH5vnPfueHzgNnJ5NmrVy9Ni2HDPO86qn36lB7vSZ8bb3TuxYEHlj+tY4910qrs/5TsZ999Vf/618yl17dvZtLx38MTT8xMmsOHpxa/U6fg8Nmz08v/scdUt21T3X//1K/Nyio93rUr8tzRR1d8uamIT7duqZWXNEhUvwYGZuIDtAR6use5wFdAl6g4hwCN3eNjgI99574DmqWSZ0YURKZe7t3x8803mUtLtfL/T7Kfdu0yqyD2xHuY7Gfs2PSv9SuItWsr/79UtU+aJFIQoZmYVHU1sNo93iQii4FWbo/Ci+Of4/kR0DoseZImkx5KdzeCpmOmS9Dc+KpKOgPyFUGQn6/dnfJsMuV/ThWwBsCooEFqEckDegAfJ4h2AeCfhqPANBGZIyIjQxQvkjC36tyTCFp4VVWpqgoieoW3YVQwoQ9Si0h94DlgtKoGrlASkcNxFIR/FGyAqq4UkRbAdBFZoqozA64dCYwEaOtfEZwupiAyQ7TfparM6tVOJ72qkckd+6oKdeqE48bbCIVQa0MRycZRDpNUNdAXhIh0Ax4HTlTVkknbqrrS/f4ZeAEInIqiquNVtUBVC5o3b15+oeP5RAFnSqCReU49tbIlKPWQWZUIckOyu2PKIZhk/I9VAqEpCBERYAKwWFUDPXSJSFvgeWCEqn7lC68nIrneMTAYWBiURkbo2tX5/u9/E+/V26JFaCLs0WRqanF5SNbZYUXycSKLrFGtCPLrVAUI08TUHxgBLBCReW7YWKAtgKqOA24EmgIPO/qEIlUtAPYCXnDDagL/VtU3QpP0llucRWaJXE9A2X5k6tYN9oppJKaqjgEYRkURvf9KFSHMWUzvAwlX96jqhUDMbiKq+g2QH5JosWRnl60cwDExJXKuZwoiPcLet7giaNYsdf9bhuFRnt3zGjaM3QMlQ9iIbCKOOCJSITz6KPz5z86q0KCVrVW0FVDl8Xba253Z05VDJsb/9mTKU3esXw+tw1khYAoiiKVLHTcCb74J++7rhDVrBvXrOztEXXBBsIIoz4YmqXLjjRWXVybwb5jjJzfX2cMgUyTaXyMsPJcRuxN9+5bv+mjngVV0kLXSaNSo9DgZt+x+BdG4ccbFSRdTEEHst1/ZHlSDnN796U+lx/4pt/FcW6dC9AIj7wVv2jTS9XVVJd6m8L/+mp67df/ua+C48F67Fo4/PvW0yks6s9uS3fciLKK3z0yV6AWlu9O05lSoXz+96x57rNTHVjLK029ievppp3xs3ux45PUYNMj57t490hFgiJiCKAtvXUQyO2Hl5JR6Mv3DH5zvQYNiB7dTXbF84IGON0g/Xos8L680L3CcxH3ySakbaT9/+5uj2JLZNS3TxNtbICsrcg1CvJliffs6O4p5Tt+OPTZyH4fp0x2nh2W52L7vvsjfTZqUbwbJccelN023ItZdXHxx/HPpKgjPhXv0eqEDDkg9rbZtM9t79FNQUP406teP3Ps8FWrVKq0zkmkg5uSUHm/b5uzfXbdupCPFli2d7wEDkvPcnAFMQZRF06ZOzyB6GqT3sHJyYNIkOOssp7LzTD9//KNjl/ZWwy5aVHrtsGGpyRBt312ypHTmT7TyOeUUZ9exNm1iPcNedZXTWi9rz+YlS1KTLxn69Inv4tv7L6NGOZv8RLNsGXz4obNfhqeAd+2CvfYqjeP1Qnr0cL6PPdbpVZx+euROYl4rrF075/viiyM3ELrkktLjZFy/v/qqk3cil9UPPFB2Osnwm9+kFv/gg+OfO/302LBXXgnuDV1+eenxvHlO+b3qqlIz05gxwQtMW7SA66+PL0PjxsGDqyJw5pnOjofpMmRIer0af4t9x47I/3XllaXHp58eO7DsL0fZ2U4Z7NDB8crrEbQd6vnnR26k5F8rcsghTi/7738vfZ6eTIcdVn5TYVnEc9K0O37SdtaXDtOmOQ6yevZMLv6PP5Y61Tr77EgnW+eem9gJ1z//6aThd8r13nvOcf/+sef8eOEzZwaHex+/w8IlS9J3GPavf8WG1apVmu+uXaoLF0bKe/XVzvFddwXLtn176fXPPuuEnXqq8/vxx1VfeCHyv337bfz7MG+e8921q+qOHY48ydy/shyk7dqlesEFsecHDw5O5+WXVd9/X7VLF+f3FVcEp//aa6oizvE77zjfbduqbtig+tFHsfHvuqv0uLg4vtzz58d6RH3rLdXvv4+N+8gjwffnnnucsNGjVYuKYq+7+mon3tatqpddFnv+yiud82+8ERk+eXLs/VdV/fDD0nfO+77++uD/N3VqpEzjxjnf3v0G1c8/j73uyScjf3/yifPt1S0tWji/jz/ecW758suqI0aoHnecc/6II5zz06cHl6PNmyPT/9vfYsvgs8/GlkNV1XvvLS0rGYTK8OZaGZ8KVRA//ODcvmuvTf4arwAsXhxZuKMVRrxKyP/77bed40GDYs8F5Rkv3PucdJLql186L3t0xVKvXmnBB9Ujj3S+69RR/fTTyLiecmnSxFFsoHrwwZF5b9+ueuihTgWpqnrbbU688eOd319/7VTyXpo7dsTe96lTk7/vqqq//OJ4APUUxIABsfeja9f492nUKNUhQyL/a/fusfFHj1bNy1OtUcOJc/vtTvivv6pu3BhZBlRV77jD+X3NNcHP/ptvSivETz910tiyJVY+7+OvFFVVFyxwjnNzS8Nffz34+mnTSsO/+cZRADfc4OQXVI4efdQJu/TSWGUDqmPGRKbnP/f1147iUHWUlf/cM8/EyuexdKnqSy9Fph+d7+bNTrgn0+9+54S1a6f65puRaUZf++qrzrPynu8XXzjHQ4c68b1yOXFi7LP3/uc550Q2avz5bN8e/G7743gKIxq/Qs4gpiDC4ttvnRcyWe66S/X++0t/P/ig8wguucT57tTJCf/oI9WjjnJaJzfdVBq/f3/nGlXVTZucvRs+/tj57bUyo1m8WHXFitjwL79U/d//VC+/3Lnu5JMjz3uFde7c2Gu9l6Rt28i4oLp6tZYoHFWn1btuXeL7sn276sMPx97L6dNVzzor/guTDtu3OxXa/PmR4Vu2xL7UqrEv8t57O7/z8pyKJBHffeco20TpeYp+6lTVP/0ptsJavry017RhQ2weTz3lKHBQ/fOfS/OoU8c5Li52WrdvveU8m3nzguW59trEZTmoQtu6VXXkSNU1ayLj/PGPzvef/hScRnQ6ixZFnvMrsFNPLX0vPHbtUn366dLn5V13/vnB70A0H3wQX7l4Ze2DD5xGharTcPH+o6qTb6plcvp0p6cU3dPyExTm5+67nfNezytDmIKoqhQWOq2Nn392KvqVK9NP6/vv07t+6lSnGJx3XmT4+PGqt94afM3y5c41nnnr0UdVe/d2XipVx5y1aVPqslRFWrVSbdmy9HdhoaP0vFZqqnz4oerzz0eG+RXonXc6FaRXWaxfX3aamzY5CtZTRqtWla2UPbyNdsrihx9Kez3xAKc3PGOGc/zWW5HnPTOTZx708MwuXi919erkZPfnm8x/SHQtqPbokV4aqeDvad17b7As8fBMfV5DIEMkUhDinK8eFBQU6Oxk9gE2Stm1y9ne8sILU/OJNGkSDB5c/RdIedOZK9rL7/btsHy5M+U6THbscGbNZMIf1qZNzsBtVpZzHD0VORmKi1Pfk2XMGLjjDqd6TZUpU5zve+913oN+/VJPI1WKi53yFD29e8YMaN++dO1VNDt3OjJedlnkrKdyIiJz1HFxFHvOFIRhGMaeSyIFYdNcDcMwjEBMQRiGYRiBmIIwDMMwAjEFYRiGYQRiCqIas7M4wKGgYRhGkpiCqKZ8sWoDHa9/nZlfralsUQzD2E0JbUc5EWkDPIWzfagC41X171FxzgSuxdl5bhNwiap+7p4bCvwdyAIeV9U7wpIVIP/P09iwdSetG9dhxa/VZ2P1syd+UiH5NM+tzZpN1WDjH6BmDaFoVzjTv/ffK5cvf9oUStq7C7WyarDDercp06ReLdZtjr/74re3H4uk4zo/AWHuSV0EXKWqc0UkF5gjItNV1efWlG+BQar6q4gcA4wHDhaRLOAh4GhgBfCpiLwcdW1G2bDVcclbnZRDRbIrpAq1MghLOQB7vHIATDmkSSLlAGRcOUCIJiZVXa2qc93jTcBioFVUnFmq+qv78yPA2zevD/C1qn6jqjuAZ4ATw5J1287ilK+pWSPzD6PrPhlYzVpJ9M5rUtkiJMXlR3akTnb8lbrN6tfin+f1TiqtMw9uy/H5+9C4bhJ7hbhkZ2W+3HjUqum8zs3q1yavaTn2OA7gksPirO4FDu2U2mr6T64/kjZNqt72vCKx7/VlR4S8kj1D3HN6fijphtmDKEFE8oAewMcJol0AvO4etwKW+86tAAKd24vISGAkQFv/Lm4psL0o9RbNoyN6ccGT5V+1PfbYztz2mrP/wtTLB6Kq/Hf2Cv7vudJNfT4ZeyR9bivdj6JurSzGjyjgrAmRt/Ptqw9j1fqtjJ4yjzWbtvPKqAE0rJPN1p3FDLl/ZkTcmdccTtumdcm7LnZnqgY5NXlmZD/+M3s5T8z6jhoC39x+HKrK21/+TK92Tcj/c+RGKnVrZzFlZF9+O/6jmPTO65/HPz/4DnBewt8P2pfRR3Wkds0sOoyZyi6Fa4d2pk/7xvRq14SlP20iq4Zw22tLmLH4Jx4d0YuLn54T9x5+d8dxABH/pWOL+iz9ubDk98COzXj6AqcIXXl0J3YW72LWsrUMilO5TRnZlwP2acCQ+2ayesM2Xrt8IFt3FrPs50J+07tNTHwv7xPy9+HyI/djvxalbibWb9lB979MB2DpX4/lppcW8uSH3wNww3EH8Or81cxbvj4mzY/HHsmiVRupWyuLzns34L4ZX/HELOc+PnV+Hw7t1Jz7Z3zF/TOWcvmRHbny6E4R1w/7x3ssXLmR/1zcj3e/+plzD2nP0p828fmKDTSrX4sOzesDyvwVG9i2cxcD9mvGQa0b8vzcFVz5n89L0nnodz05rltLrh3amW07i5nw/recXtCaFrml7h6iy9FtJx/E58vX079jMy6f/FlJWL99m9IiN4f3/u+IkvI0qFMLsmoIazZt5z+zl3N+//bkZNfgna/W0KFZPbbsKGbTtiL23yuXhlHK2J9vvVpZvDSqf8m9X7BiA8c/+D7gKKX1W3Yy+L6Z5GTXYNtO552ff/NgFq3ayC5VWuTmsF8LZwe508fN4tPvfqVfh6ZcOKAD+X+JLO/f3XEcn/3wKyc/PIvOe+ey5MfInuFXtx7D2s3bee+rX9inUZ2Sd/XZ3/djrwY5vDp/NXe+sYTsLOGJ8/pw5uMfs0/DHFZtiN1Ya/7Ng+l2c/yNi/q0b8KpvcLZkzp0BSEi9YHngNGqujFOnMNxFMSAVNNX1fE4pikKCgrSsg0Up2FSyM7KTOcr2tOJiHDkAZG7qjWok03bJnX5Yd0WALJEAnfpbN+sHu2b1aO225IUgbZxWpJB4c3q1+aXwu0c0LIBXfZpwAUD2pdUSJ5sR3Tei607AnpcCgd3aBqYl9eyBWhYJ5trh8buIjasW0vaNHFk6rhXGj58otirQU6EgogmO6tGXOUAsf8lq4bQq11jerVLvF9wXrN6EcoBEnf9u7RswGc/rA9UEHs1yGGvBsE+d1KxJmTVEK4Z4tzz5rm1OWS/yP3Be7VrEhPfz+GdS+9TTnYWfzi87Fb1wR2a8LuDnQabpyDO6NMm4l545cmjeW7tiLQP3z/O7oI+9m6Qw48bnUq1TZO6Eff+oNYNS45b5Oaw0TUj1/DJ0CAnm75xyq0nY8O62Qzpuhf/+yJyM6vo+wSQ17Qu363dQnaW0LJhHX7Tuw0/rN1Scr7A7WkP69aSO99Y4ubhnKsRxyrRICf5HmqmCXUWk4hk4yiHSar6fJw43YDHgRNVda0bvBLwN9Nau2GhUBS0v3QZZEpBBBFd8LJqCP6grCTNFEEFOBk8nRWvwKbqty7L90JmxanZ4uWVCm+MHlhiPorOprwux8rzuBM+h/AsTsnlH0C0QquRhm076DmHYSNXkn+wXv7xymAQ3q372+n5MabHoPvy398fwuSL+kb815oB72tEeXf/Qrrva5iEVsuJc4cmAItV9d44cdoCzwMjVPUr36lPgY4i0l5EagHDgZfDkrWoOPXaI+ihZ4roFylLJKIw1iyjhi5pkZTzhYxXXoPyT3QH/XLEVToBwamK33nvBnTcK81N5ssgqxzeXCv7vU81/2gHnulUXOUte8mSiuL3ZEpFNO9dzM3JjunRBP3H5rm16bdvZI8kaLwySElVRQURpompPzACWCAi89ywsUBbAFUdB9wINAUedh9EkaoWqGqRiIwC/oczzXWiqn4RlqDpmJjCfAGiy0mNGhJRsSY7QJ52eVPv+uQr80T4k4l3baL7mUol4MWNviaVlmZQeqm0OqOJ/m8xkpSjKCVzb6Sc3ZR0/nsF6YeU8MpepnoyyZapoIrfa28IUvL80574EuIEwtAUhKq+TxlFX1UvBC6Mc+414LUQRIshnRXHmXoBgp5tUGUZYaZJsiCl+iJER493eVC6idzG++PHUwRBweW5xekqhHjplGc7iIqoLDOZRey4WOppZMJkmAypPOV0ehCZoGaAfTLoPaioXlcq2Epq0utBZIqgejWw8Ph7EEmat1Ju6SchRzr4lVu8FIPySuepeMmUt9UcTXm6/9H/LTqlZFNO9DgyWYKjlWs6Le6Kspb435+yelOZrn+TLWMJTUz+scUqaGIyBQH8umVnyteEuc9SUGu1RhoFKf1BaufPpWJaSHQ7khngLY8JJ4joSq68z6s8CidT/y3TSi8emSjbmX6emaCyWuhlDlK7mIKoovzm0Q8rLe+TeuwTExZoYkpjDCLVCiU621ReqESVSjIt0KC8qtLrUp66ZXczMWViJXkYM5aCOLSTM2V3n4Y53HR8l4RxM6Ug2qW4CDFoUof3PktAmMcZfdryh8PjL1CsCCpkoVx1oU52Flt9q67PPSQvYp1APHJr12TT9qKY8Ad/14OWDWNXlJZVWZZnRk0qSArZJDuLKb28glN/6vw+dKmg1eflqVrKqiwrqjJNlnQ8C0Tjr+umXj6AZWs2lzvNIG4/5SBGH9kp7nqfeDKly0djjqRe7dT2zA7KN6iHFd3wu/2Ug1LKJwysB5EkDetkp90F3H/v4IVf8Vr4gdkkYcePTjfVgdroijxTLa5kblugUizjusZ1a9Gsfu00paoehGHp3BK0EDJF/M+z6z4NOSE/tqecCWrXzEpKOUBmFPHeDXPITXHhWlC+QaKk+75lakJGEKYg4tCrXeOIrmQNgft+273kd5eWDUoGt1s1qsMZfdrQx+eP6Iw+bSP84fzjjB4M6tScK4/uRP/9mtJ571wGdHS6x/83dH/OPLjUTYi/QB170N4AEd3noBbM2f3alRwHFZjj3Re0/35NuWhg+5LwW07sSt8OTchv04h7fpNPl5YNuP64LiX/OR6eXOB0uS93fdb4/4fH0ANL4/7jdz0D00tF93ors4PWPNx8QlcObNWAW048EIDTerXmgJYNGHPMAcln4OOe07vTs20jmtSrlTBeKo2HCwZ0iPh9+RH7RZS1UYfvV7IK2c95/fOSzqM8nNKjFZ33zuWqoztxdJe9yr4Ax32Knyo5IyfDIu3boh7dWjfklpMOTPna2jVr0Kd9Ex4+syfd2zRy37v4ZfSSw/ZN6A8rLMzEBOzVoDaHdWrBrScfSMfrHXdQz11yCABrC7fT69YZiEiJvROgTq0sdrg+nEYdsR9n9Il9oT/9bh2nj3PGN47P36ekkoaOEfEuPSy+64KHz+wFQM+2jUvCateMVRB/OTG2kPp7KP84owf/OKNHTJwR/fIY0S+v5PdrVwwsOU70kntyRfP7Qfsy6eMfaN24Dj9u2EbRLqVp/dol/pLikUqF8tWtx8Q917NtY169zPkPZeWZDAM6NitR5Im47Ij9uH/G0qTSbNu0Ln07NOGjb9YBjmuRd685vMzr2jSpy4D9mvH+17+UhIVRDbdokMMbow9N6ZrrjunMdcd05qCb/sem7UUpmScrikyb8mrXzOLlUSl7ByqR5T8X9yv57b131w7tzJ1vLOHiQZGNCM89zSPvLItNK8TRuir4GCueomIlu6aU6T4j2m7orZ+oFee6sGY6+X0bBZGuiSma8q/EFve7fHmFOWNsd8duTfJUvT5NZjATU8jsKN5VpvsKiK3EtrsKIrusCjvDJTNMl9F+ytslT2UsPdDVRrV9pTNPFbTo7FHk1q4YY0zTMkydmcYUBE4Pwt8q9/uqr+06fzu4fZOSl7Cf6/2xS0tnBk2bxsG+7ZvVdx5mfutGacl1YKvgGTr5bRrRIjf+4GxBnmOOqlfOQuspxP77lW1i8fDy7J3XhAHudYl6B17aQd1/7/+3bFSHlg0dr6Z9qui+E/s2r+9+14sbp2OL0jGT/DaNAGie4iB7N9dDaXP3+XvuqTs0jx2P8cySjVLYr6K89HX9EGVX0Ey7ZIg3LdwrU0F0d59P0/rJVcjvX3cEH489MmGc5gneWY8Obvnp2CJ4YstbVx0GELGnSbr1S1KoarX59OrVS9PhjYWrddGqDaqq+u2aQl2/eUfE+S9/3KhbdxSpqurSnzZp4badqqpaVLxLF6xYnzDtL1Zu0B1FxSnLtOznTbpxa6Qc7a59Vdtd+6oWF+9SVdWFK9fril+36I8btkbE27azSBev3pBynkEs/Wmjbt6+M6Vrlqx27teW7UX61Y8bE8bdvH2nLv0pOE6x7/6u37xD31r8U8m9r2rs2rVL5y9fr7t27Qo8/82aQt3ge547i4p14crEZSeI6OsS5bt9Z3FJua4oknnmFcnydZv1l03bVFX1183btd21r2rf22bod7/Evud+0n0+8fj+l8366+btScVNVI5US9/JBSvW68KV69OqX/wAszVOnSpajQy8BQUFOnt2+Tfxqao8/eF35LdpRLcwWwyGUY15+J2vOebAlrRvFr+nt6chInNUtSDonM1i2o3wzzYyDCN1Es0YNGKpOoZCwzAMo0phCsIwDMMIxBSEYRiGEYgpCMMwDCOQMPekbiMib4vIIhH5QkSuCIjTWUQ+FJHtInJ11LnvRGSBiMwTkeo7NckwDKOKEuYspiLgKlWdKyK5wBwRma6qi3xx1gGXAyfFSeNwVf0lzjnDMAwjRELrQajqalWd6x5vAhYDraLi/KyqnwKpb+lmGIZhhEqFjEGISB7QA/g4hcsUmCYic0RkZIK0R4rIbBGZvWbNmnJKahiGYXiEvlBOROoDzwGjVXVjCpcOUNWVItICmC4iS1R1ZnQkVR0PjHfzWiMi36cpajOgKpqzTK7UMLlSw+RKjeooV7t4J0JVECKSjaMcJqnq86lcq6or3e+fReQFoA8QoyCirmleDllnx1tuXpmYXKlhcqWGyZUae5pcYc5iEmACsFhV703x2nruwDYiUg8YDCzMvJSGYRhGPMLsQfQHRgALRGSeGzYWaAugquNEZG9gNtAA2CUio4EuON2lF1wX0DWBf6vqGyHKahiGYUQRmoJQ1fcpYxMnVf0RaB1waiOQH4ZcCRhfwfkli8mVGiZXaphcqbFHyVWt3H0bhmEYmcNcbRiGYRiBmIIwDMMwAtnjFYSIDBWRL0XkaxG5roLzDvRXJSI3i8hK1w/VPBE51nfNGFfWL0VkSIiyxfjCEpEmIjJdRJa6343dcBGRB1y55otIz5Bk2t93T+aJyEYRGV1Z90tEJorIzyKy0BeW8j0SkXPc+EtF5JyQ5LpbRJa4eb8gIo3c8DwR2eq7d+N81/Ryy8DXruwJxxTTlCvlZ5fpdzaOXFN8Mn3nTbSpqPuVoG6o2PIVby/SPeEDZAHLgA5ALeBzoEsF5t8S6Oke5wJf4cziuhm4OiB+F1fG2kB7V/askGT7DmgWFXYXcJ17fB1wp3t8LPA6zqSEvsDHFfTsfsRZ5FMp9ws4FOgJLEz3HgFNgG/c78buceMQ5BoM1HSP7/TJleePF5XOJ66s4sp+TAhypfTswnhng+SKOn8PcGNF3q8EdUOFlq89vQfRB/haVb9R1R3AM8CJFZW5JuGvKooTgWdUdbuqfgt8jfMfKooTgSfd4ycpdbJ4IvCUOnwENBKRliHLciSwTFUTrZwP9X6ps7J/XUCeqdyjIcB0VV2nqr8C04GhmZZLVaepapH78yOCZw+W4MrWQFU/UqemeYr4TjXTlisB8Z5dxt/ZRHK5vYDfAJMTpZHp+5WgbqjQ8rWnK4hWwHLf7xUkrqBDQ2L9VY1yu4oTvW4kFStvkC+svVR1tXv8I7BXJcjlMZzIl7ay75dHqveoMmQ8H6e16dFeRD4TkXdFZKAb1sqVpSLkSuXZVfT9Ggj8pKpLfWEVer+i6oYKLV97uoKoEkisv6pHgH2B7sBqnC5uRTNAVXsCxwB/EJFD/SfdVlKlzJEWkVrACcB/3aCqcL9iqMx7FA8RuR7HFf8kN2g10FZVewBXAv8WkQYVKFKVfHY+ziCyIVKh9yugbiihIsrXnq4gVgJtfL9bu2EVhgT4q1LVn1S1WFV3AY9RahapMHnV5wsL8Hxh/eSZjtzvnytaLpdjgLmq+pMrY6XfLx+p3qMKk1FEzgWGAWe6lQuuCWetezwHx77fyZXBb4YKRa40nl1F3q+awCnAFJ+8FXa/guoGKrh87ekK4lOgo4i0d1ulw4GXKypz174Z468qyn5/MqV+qF4GhotIbRFpD3TEGRjLtFzxfGG9DHizIM4BXvLJdbY7k6IvsMHXDQ6DiFZdZd+vKFK9R/8DBotIY9e8MtgNyygiMhT4P+AEVd3iC28uIlnucQece/SNK9tGEenrltOzff8lk3Kl+uwq8p09CliiqiWmo4q6X/HqBiq6fKU7yl5dPjij/1/htASur+C8B+B0EecD89zPscDTwAI3/GWgpe+a611Zv6Scs0oSyNUBZ3bI58AX3n0BmgJvAkuBGUATN1yAh1y5FgAFId6zesBaoKEvrFLuF46SWo2z4dUK4IJ07hHOmMDX7ue8kOT6GscW7ZWzcW7cU91nPA+YCxzvS6cAp8JeBjyI63khw3Kl/Owy/c4GyeWGPwH8Pipuhdwv4tcNFVq+zNWGYRiGEciebmIyDMMw4mAKwjAMwwjEFIRhGIYRiCkIwzAMIxBTEIZhGEYgpiAMIwVEpFgiPcpmzAOwOJ5Cbe91o8oQ5p7UhlEd2aqq3StbCMOoCKwHYRgZQJw9A+4SZz+AT0RkPzc8T0Tecp3RvSkibd3wvcTZl+Fz93OIm1SWiDwmzh4A00SkTqX9KWOPxxSEYaRGnSgT02995zao6kE4q2jvd8P+ATypqt1wHOQ94IY/ALyrqvk4exF84YZ3BB5S1a7AepyVu4ZRKdhKasNIAREpVNX6AeHfAUeo6jeuk7UfVbWpiPyC4z5ipxu+WlWbicgaoLWqbvelkYfju7+j+/taIFtVb62Av2YYMVgPwjAyh8Y5ToXtvuNibJzQqERMQRhG5vit7/tD93gWjsdRgDOB99zjN4FLAEQkS0QaVpSQhpEs1joxjNSoI+4G9i5vqKo31bWxiMzH6QWc4YZdBvxTRK4B1gDnueFXAONF5AKcnsIlOB5FDaPKYGMQhpEB3DGIAlX9pbJlMYxMYSYmwzAMIxDrQRiGYRiBWA/CMAzDCMQUhGEYhhGIKQjDMAwjEFMQhmEYRiCmIAzDMIxA/h96DsJ4TGEuOAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "all_best_distance, all_best_path, best_distances, avg_distances = ACO()\n",
    "\n",
    "plt.plot(best_distances, label = \"Best Distance\")\n",
    "plt.plot(avg_distances, color = \"r\", label = \"Avg Distance\")\n",
    "plt.legend()\n",
    "plt.xlabel(\"Epoch\")\n",
    "plt.ylabel(\"Path Distance\")\n",
    "print(all_best_distance)\n",
    "print(all_best_path)\n",
    "print(computePathDistance(all_best_path))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "visualizer(all_best_path)"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "79c38198e3a853eeea51b70a0ae21c719ed1444592bdd4a45c4de9d24fbfec7c"
  },
  "kernelspec": {
   "display_name": "Python 3.7.7 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
